home *** CD-ROM | disk | FTP | other *** search
- /* +-------------------------------------------------------------------+ */
- /* | Copyright 1992, 1993, David Koblas (koblas@netcom.com) | */
- /* | | */
- /* | Permission to use, copy, modify, and to distribute this software | */
- /* | and its documentation for any purpose is hereby granted without | */
- /* | fee, provided that the above copyright notice appear in all | */
- /* | copies and that both that copyright notice and this permission | */
- /* | notice appear in supporting documentation. There is no | */
- /* | representations about the suitability of this software for | */
- /* | any purpose. this software is provided "as is" without express | */
- /* | or implied warranty. | */
- /* | | */
- /* +-------------------------------------------------------------------+ */
-
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <X11/Xaw/Command.h>
- #include <X11/Xaw/Toggle.h>
- #include <X11/Xaw/Viewport.h>
- #include <X11/Xaw/Box.h>
- #include <X11/Xaw/Form.h>
- #include <X11/Xaw/Scrollbar.h>
- #include <X11/Shell.h>
- #include <X11/cursorfont.h>
- #include <stdio.h>
- #ifndef NOSTDHDRS
- #include <stdlib.h>
- #include <unistd.h>
- #endif
- #include "Paint.h"
- #include "xpaint.h"
- #include "palette.h"
- #include "menu.h"
- #include "misc.h"
- #include "cutCopyPaste.h"
-
- #define PADDING 4
- #define BW 1
-
- typedef struct LocalInfo_s {
- int curX, curY;
- int offX, offY, baseX, baseY;
- Widget cursor; /* The Box widget */
- Widget subpaint; /* the paint widget inside the box */
- Widget view; /* the widget in the popup window */
- Widget paint; /* The source of this zoom */
- Widget shell;
-
- int zoom; /* paint widget zoom value */
- Position spX, spY;
- Dimension spBW; /* subpaint, x, y and borderwidth */
- struct LocalInfo_s *next;
- } LocalInfo;
-
- static LocalInfo *head = NULL;
-
- /*
- ** When the popup window is gone, free the storage
- */
- static void destroyCallback(Widget w, XtPointer larg, void *junk2)
- {
- LocalInfo *l = (LocalInfo *)larg;
- LocalInfo *c = head, **p = &head;
-
- while (c != NULL && c != l) {
- p = &c->next;
- c = c->next;
- }
-
- if (c != NULL)
- *p = l->next;
-
- XtFree((XtPointer)l);
- }
-
- /*
- ** Done or WM-Close pressed, destroy widgets
- */
- static void doneCallback(Widget w, XtPointer larg, void *junk2)
- {
- LocalInfo *l = (LocalInfo *)larg;
-
- /*
- ** Destroy both the cursor and the popup window
- */
- XtDestroyWidget(l->cursor);
- XtDestroyWidget(GetShell(w));
- }
-
- /*
- ** Move the cursor and the view window to the position
- ** specified by x,y
- */
- static void moveCursor(LocalInfo *l, int x, int y, int w, int h)
- {
- int dw, dh;
- int rx, ry;
-
- if (w == -1 || h == -1) {
- int z;
- Dimension wt, ht;
-
- XtVaGetValues(l->view, XtNzoom, &z,
- XtNwidth, &wt,
- XtNheight, &ht,
- NULL),
-
- w = (wt + z - 1) / z;
- h = (ht + z - 1) / z;
- }
-
- XtVaGetValues(l->paint, XtNdrawWidth, &dw, XtNdrawHeight, &dh, NULL);
- if (x < 0) x = 0;
- if (y < 0) y = 0;
- if (x + w > dw) x = dw - w;
- if (y + h > dh) y = dh - h;
- if (x < 0 || y < 0) {
- int z;
-
- XtVaGetValues(l->view, XtNzoom, &z, NULL);
-
- /* XXX zoom bigger than actual */
- return;
- }
-
- rx = x / l->zoom;
- ry = y / l->zoom;
- x = rx * l->zoom;
- y = ry * l->zoom;
-
- XtVaSetValues(l->view, XtNzoomX, rx, XtNzoomY, ry, NULL);
- XtVaSetValues(l->cursor, XtNx, x - l->spX - l->spBW - 1,
- XtNy, y - l->spY - l->spBW - 1, NULL);
- XtVaSetValues(l->subpaint, XtNzoomX, rx, XtNzoomY, ry, NULL);
- }
-
- /*
- ** Given the popup dimensions, set the "cursor" view to the correct size
- */
- static void resizeCursor(LocalInfo *l)
- {
- Dimension width, height;
- int zoom;
- int pw,ph;
- int dw,dh;
- int zx,zy;
-
- XtVaGetValues(l->view, XtNwidth, &width,
- XtNheight, &height,
- XtNzoom, &zoom,
- NULL);
- XtVaGetValues(l->paint, XtNdrawWidth, &dw,
- XtNdrawHeight, &dh,
- XtNzoom, &l->zoom,
- NULL);
- XtVaGetValues(l->subpaint, XtNzoomX, &zx,
- XtNzoomY, &zy,
- NULL);
-
- pw = (width + zoom - 1) / zoom;
- ph = (height + zoom - 1) / zoom;
- if ((pw + zx > dw) || (ph + zy > dh)) {
- int nx,ny;
-
- nx = (pw + zx > dw) ? dw - pw : zx;
- ny = (ph + zy > dh) ? dh - ph : zy;
-
- /*
- ** If the new x or y value off the screen, set it back.
- ** and resize view
- */
- if (nx < 0 || ny < 0) {
- if (nx < 0) {
- pw += nx;
- nx = 0;
- }
- if (ny < 0) {
- ph += ny;
- ny = 0;
- }
- /* XXX -- this really should be SetValues(width,height)
- ** but that doesn't work..?/
- */
- XtResizeWidget(l->view, pw * zoom, ph * zoom, 1);
- }
- moveCursor(l, nx, ny, pw, ph);
- }
-
- pw *= l->zoom;
- ph *= l->zoom;
-
- XtVaSetValues(l->cursor, XtNwidth, pw + 2 * (PADDING + BW),
- XtNheight, ph + 2 * (PADDING + BW),
- NULL);
- XtVaSetValues(l->subpaint, XtNwidth, pw,
- XtNheight, ph,
- NULL);
- }
-
- /*
- ** Button down in the cursor window
- */
- static void press(Widget w, LocalInfo *l, XButtonEvent *event, Boolean *flg)
- {
- Position x, y;
-
- XtVaGetValues(w, XtNx, &x, XtNy, &y, NULL);
-
- l->offX = event->x;
- l->offY = event->y;
- l->baseX = event->x_root - x;
- l->baseY = event->y_root - y;
- XtVaGetValues(l->paint, XtNzoom, &l->zoom, NULL);
- }
- static void motion(Widget w, LocalInfo *l, XMotionEvent *event, Boolean *flg)
- {
- int nx, ny;
- int px, py;
-
- /*
- ** Compress motion events.
- */
- while (XCheckTypedWindowEvent(XtDisplay(w), XtWindow(w), MotionNotify, (XEvent*)event));
-
- nx = event->x_root - l->baseX;
- ny = event->y_root - l->baseY;
-
- px = nx + l->spX + l->spBW + 1;
- py = ny + l->spY + l->spBW + 1;
-
- moveCursor(l, px, py, -1, -1);
- }
-
- /*
- ** If the paint view size changes, update the parent paint window cursor size
- */
- static void sizeChanged(Widget w, LocalInfo *l, XtPointer junk)
- {
- resizeCursor(l);
- }
-
- /*
- ** The parent box widget changed size, resize to fit.
- */
- static void boxChanged(Widget w, LocalInfo *l, XConfigureEvent *event, Boolean *flg)
- {
- Dimension width, height;
- Dimension hpad, vpad, bw;
- int zoom;
-
- XtVaGetValues(l->view, XtNzoom, &zoom, XtNborderWidth, &bw,
- NULL);
- XtVaGetValues(XtParent(l->view), XtNwidth, &width,
- XtNheight, &height,
- XtNhSpace, &hpad,
- XtNvSpace, &vpad,
- NULL);
- width -= (hpad + bw) * 2 ;
- height -= (vpad + bw) * 2;
-
- /* XXX -- this really should be SetValues(width,height)
- ** but that doesn't work..?/
- */
- XtResizeWidget(l->view, width, height, 1);
-
- resizeCursor(l);
- }
-
- /*
- ** One of the zoom perctange buttons pressed
- */
- static void buttonCallback(Widget w, XtPointer lArg, void *junk2)
- {
- LocalInfo *l = (LocalInfo *)lArg;
- char *lbl;
- int nz;
- int cx, cy, zx, zy, z, nw, nh;
- int x, y;
- Dimension width, height;
- Boolean state;
-
- XtVaGetValues(w, XtNstate, &state, XtNlabel, &lbl, NULL);
-
- if (state == False)
- return;
-
- nz = 0;
- sscanf(lbl, "%*d:%d", &nz);
- if (nz == 0)
- return;
-
- XtVaGetValues(l->view, XtNzoomX, &zx,
- XtNzoomY, &zy,
- XtNzoom, &z,
- XtNwidth, &width,
- XtNheight, &height,
- NULL);
-
- cx = zx + ((width + z - 1) / z) / 2;
- cy = zy + ((height + z - 1) / z) / 2;
- nw = (width + nz - 1) / nz;
- nh = (height + nz - 1) / nz;
-
- XtVaSetValues(l->view, XtNzoom, nz, NULL);
- /* center on image center */
- x = cx - nw / 2;
- y = cy - nh / 2;
-
- moveCursor(l, x, y, width / nz, height / nz);
- }
-
- /*
- ** Construct the fatbits popup, and cursor
- **
- */
- void FatbitsEdit(Widget paint)
- {
- Widget shell, form, fat;
- Widget button, box;
- int i, zoom;
- Colormap cmap;
- Position x, y, lx, ly;
- Dimension width = 48, height = 48;
- LocalInfo *l;
- static char *zoomList[] = {
- "zoomButton1",
- "zoomButton2",
- "zoomButton3",
- "zoomButton4",
- "zoomButton5",
- };
- XtTranslations trans = XtParseTranslationTable("<BtnDown>,<BtnUp>: set() notify()");
- Widget first = None;
-
- for (l = head; l != NULL && l->paint != paint; l = l->next);
-
- if (l != NULL) {
- XMapRaised(XtDisplay(l->shell), XtWindow(l->shell));
- return;
- }
-
- l = XtNew(LocalInfo);
-
- l->paint = paint;
- l->next = head;
- head = l;
-
- XtVaGetValues(paint, XtNcolormap, &cmap,
- XtNzoom, &l->zoom,
- XtNdownX, &lx,
- XtNdownY, &ly,
- NULL);
-
- shell = XtVaCreatePopupShell("fatbits", topLevelShellWidgetClass,
- GetShell(paint), XtNcolormap, cmap,
- NULL);
- l->shell = shell;
- PaletteAddUser(PaletteFind(shell, cmap), shell);
- form = XtVaCreateManagedWidget("form", formWidgetClass, shell, NULL);
-
- box = XtVaCreateManagedWidget("fatBox", boxWidgetClass, form,
- XtNbackgroundPixmap, GetBackgroundPixmap(form),
- NULL);
- XtAddEventHandler(box, StructureNotifyMask, False, (XtEventHandler)boxChanged, (XtPointer)l);
-
-
- fat = XtVaCreateManagedWidget("paint", paintWidgetClass, box,
- XtNpaint, paint,
- XtNbottom, XtChainBottom,
- NULL);
- l->view = fat;
- XtVaGetValues(fat, XtNzoom, &zoom, NULL);
- XtVaSetValues(fat, XtNwidth, width * zoom,
- XtNheight, height * zoom,
- NULL);
-
- button = XtVaCreateManagedWidget("done", commandWidgetClass, form,
- XtNfromVert, box,
- XtNtop, XtChainBottom,
- XtNbottom, XtChainBottom,
- XtNleft, XtChainLeft,
- XtNright, XtChainLeft,
- NULL);
-
- XtAddCallback(button, XtNcallback, doneCallback, (XtPointer)l);
-
- ccpAddStdPopup(fat);
-
- first = None;
- for (i = 0; i < XtNumber(zoomList); i++) {
- button = XtVaCreateManagedWidget(zoomList[i],
- toggleWidgetClass, form,
- XtNfromHoriz, button,
- XtNfromVert, box,
- XtNtop, XtChainBottom,
- XtNbottom, XtChainBottom,
- XtNleft, XtChainRight,
- XtNright, XtChainRight,
- XtNradioGroup, first,
- XtNtranslations, trans,
- NULL);
- first = button;
- XtAddCallback(button, XtNcallback, buttonCallback, (XtPointer)l);
-
- if (i == XtNumber(zoomList) / 2) {
- XtVaSetValues(button, XtNstate, True, NULL);
- }
- }
-
- XtAddCallback(shell, XtNdestroyCallback, destroyCallback, (XtPointer)l);
- AddDestroyCallback(shell, (void (*)(Widget, void *, XEvent *))doneCallback, (XtPointer)l);
-
- XtPopup(shell, XtGrabNone);
-
- #if 0
- XtVaGetValues(fat, XtNwidth, &width, XtNheight, &height, NULL);
- #endif
-
- lx -= width / 2;
- ly -= height / 2;
- if (lx < 0) lx = 0;
- if (ly < 0) ly = 0;
-
- x = lx - (PADDING + 2);
- y = ly - (PADDING + 2);
-
- box = XtVaCreateManagedWidget("fatBox", boxWidgetClass, paint,
- XtNx, x,
- XtNy, y,
- XtNwidth, width + 2 * (PADDING + 1),
- XtNheight, height + 2 * (PADDING + 1),
- XtNborderWidth, 1,
- XtNbackgroundPixmap, GetBackgroundPixmap(paint),
- NULL);
-
- l->cursor = box;
-
- XtAddEventHandler(box, ButtonPressMask, False, (XtEventHandler)press, (XtPointer)l);
- XtAddEventHandler(box, ButtonMotionMask, False, (XtEventHandler)motion, (XtPointer)l);
-
- l->subpaint = XtVaCreateManagedWidget("fatPaint", paintWidgetClass, box,
- XtNpaint, paint,
- XtNzoom, PwZoomParent,
- XtNx, PADDING,
- XtNy, PADDING,
- XtNborderWidth, 1,
- XtNwidth, width,
- XtNheight, height,
- XtVaTypedArg, XtNcursor, XtRString, "fleur", sizeof(Cursor),
- NULL);
-
- XtAddCallback(l->view, XtNsizeChanged, (XtCallbackProc)sizeChanged, (XtPointer)l);
-
- XtVaGetValues(l->subpaint, XtNx, &l->spX,
- XtNy, &l->spY,
- XtNborderWidth, &l->spBW,
- NULL);
-
- XtVaSetValues(l->subpaint, XtNzoomX, lx, XtNzoomY, ly, NULL);
- XtVaSetValues(l->view, XtNzoomX, lx, XtNzoomY, ly, NULL);
-
- /*
- ** Set the current operator
- */
- GraphicAdd(fat);
- StateAddParent(shell, paint);
- }
-